package com.example.mysql.学习笔记.高级.事务.锁.锁的分类.从粒度划分;

public class InnoDB的行锁 {
}
/**
 *2. InnoDB中的行锁   因为MyISAM不支持行锁
 * 行锁(Row Lock)也称为记录锁，顾名思义，就是锁住某-行(某条记录row)。
 * 需要的注意的是，MySQL 服务器层并没有实现行锁机制，行级锁只在存储引擎层实现。
 * 优点:锁定力度小，发生锁冲突概率低，可以实现的并发度高。
 * 缺点:对于锁的开销比较大，加锁会比较慢，容易出现死锁情况。
 *
 *
 */
/**
 * ①记录锁(Record Locks)
 * 记录锁也就是仅仅把一条记录锁上，官方的类型名称为: LOCK_REC_NOT_GAP。
 * 比如我们把id值为8的那条记录加一个记录锁
 * 仅仅是锁住了id值为8的记录，对周围的数据没有影响。
 *
 */

/**
 * ②间隙锁(Gap Locks)  简单来说就是让此纪录的左右间隙两边不可以插入数据
 *                    比如有id=3和8  你在5上加了个锁，其实并没有此数据
 *                    但是间隙锁可以让你（3，8）之间都不可以插入
 *                    但是如果最大20，你锁了25  那么（20，+无穷）
 * MySQL在REPEATABLE READ 隔离级别下是可以解决幻读问题的,解决方案有两种，
 * 可以使用MVCC方案解决,也可以采用加锁方案解决。
 * 但是在使用加锁方案解决时有个大问题，就是事务在第一次执行读取操作时，
 * 那些幻影记录尚不存在，我们无法给这些幻影记录加上记录锁。
 * InnoDB提出了一种称之为Gap Locks 的锁，官方的类型名称为: LOCK GAP，
 * 我们可以简称为gap锁。
 * gap锁的提出仅仅是为了防止插入幻影记录而提出的。
 * 虽然有共享gap锁和独占gap锁这样的说法，但是它们起到的作用是相同的。
 * 而且如果对一条记录加了gap锁(不论是共享gap锁还是独占gap锁) ,
 * 并不会限制其他事务对这条记录加记录锁或者继续加gap锁。
 *
 *
 * 间隙锁的引入，可能会导致同样的语句锁住更大的范围，这其实是影响了并发度的。
 * 下面的例子 会产生死锁
 * 如有id=3和8  其中一个事务在5上加了个锁，
 *             另一个事务在6上加了个锁，  会产生死锁
 *   但是mysql智能  他会自己结束一个成本最低的锁或者到超时自动结束
 *
 */

/**
 * ③临键锁(Next-Key Locks)  = 间隙锁+记录锁
 * 有时候我们既想锁住某条记录，又想阻止其他事务在该记录前边的间隙插入新记录,
 * 所以InnoDB就提出了一种称之为Next-Key Locks 的锁，.
 * 官方的类型名称为: LOCK_ORDINARY，我们也可以简称为next-key锁。
 * Next-Key Locks是在存储引擎innodb、事务级别在可重复读的情况下使用的数据库锁，
 * innodb默认的锁就是Next-Key locks。
 * 比如，我们把d值为8的那条记录加一个next-key锁的示意图如下:
 *
 * next-key锁的本质就是一个记录锁和一个gap锁的合体，
 * 它既能保护该条记录，又能阻止别的事务将新记录插入被保护记录前边的间隙
 *
 * 如select * from 表名 where id>5 and id<=8 FOR UPDATE
 * 直接锁定了（5，8]  范围
 *
 *
 */

/**
 * ④插入意向锁(Insert Intention Locks) (他是行级锁)
 * InnoDB规定事务在等待的时候也需要在内存中生成一个锁结构
 *
 * 比如在有了临建锁时 如（3，8）
 * 其他事务  一个插入id=5
 *          一个插入id=6   两者互不影响 还好
 * 如果都是插入 id=5  那么会冲突  所以需要插入意向锁
 * InnoDB规定事务在等待的时候也需要在内存中生成一个锁结构
 *
 * 插入意向锁并不会阻止别的事务继续获取该记录.上任何类型的锁。
 *
 *
 *
 */